/***************************************************************************
 *   Copyright (C) 2007 by Ivan Vasić                                      *
 *   ivasic@gmail.com                                                      *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "mysqlmodeltorrent.h"
#include "exceptions.h"
#include "bencoding.h"

#include <QtCore>
#include <QtSql>

#include <QStandardItem>

MySQLModelTorrent::MySQLModelTorrent(const QString id, QObject *parent)
		: ModelTorrent(id, parent)
{
	update();
}


MySQLModelTorrent::~MySQLModelTorrent()
{}

QStringList MySQLModelTorrent::getPropertiesMap() const
{
	QStringList ret;

	ret << "Infohash";
	ret << m_infohash;

	ret << "Torrent name";
	ret << m_name;

	ret << "Description";
	ret << m_description;

	///@TODO: Dodaj i ostale parametre

	return ret;
}

void MySQLModelTorrent::update()
{
	QSqlQuery query;
	query.prepare("SELECT * FROM Torrent WHERE Name = ?");
	query.bindValue(0, this->id(), QSql::In);
	query.exec();

	if (query.lastError().type() != QSqlError::NoError)
		throw new DBException(query.lastError().text(), Exception::Normal, __FILE__, __FUNCTION__, __LINE__);

	if (!query.next())
	{
		m_isValid = FALSE;
		return;
	}

	m_isValid = TRUE;

	m_infohash = query.record().value("INFO_HASH").toString();
	m_description = query.record().value("description").toString();
	m_name = query.record().value("Name").toString();
	m_size = query.record().value("Size").toULongLong();
	m_added = query.record().value("Added").toDateTime();
	m_uploadedBy = query.record().value("UploadedBy").toString();
}

void MySQLModelTorrent::remove()
{
	QSqlQuery query;
	query.prepare("DELETE FROM Torrent WHERE INFO_HASH = ?");
	query.bindValue(0, m_infohash, QSql::In);
	query.exec();

	if (query.lastError().type() != QSqlError::NoError)
		throw new DBException(query.lastError().text(), Exception::Normal, __FILE__, __FUNCTION__, __LINE__);

	m_isValid = FALSE;
}


QByteArray MySQLModelTorrent::metainfo() const
{
	QSqlQuery query;
	query.prepare("SELECT metainfo FROM Torrent WHERE Name = ?");
	query.bindValue(0, this->id(), QSql::In);
	query.exec();

	if (query.lastError().type() != QSqlError::NoError)
		throw new DBException(query.lastError().text(), Exception::Normal, __FILE__, __FUNCTION__, __LINE__);

	if (!query.next())
		throw new DBException(QString("Torrent does not exist"), Exception::Normal, __FILE__, __FUNCTION__, __LINE__);

	return query.record().value("metainfo").toByteArray();
}


QStandardItemModel* MySQLModelTorrent::getFilesModel() const
{
	QStandardItemModel* model = new QStandardItemModel();
	model->setHorizontalHeaderLabels(QStringList(tr("Filename")));
	QStandardItem *rootItem = model->invisibleRootItem();
		
	QByteArray metainfo = this->metainfo();
	
	//Prvo dekodiraj torrent metainfo
	BDecoder dec(metainfo);
	BNode* root = dec.decode();

	//Ako nije uspeo da dekodira ili rezultat nije BDict (sto je nepravilno) throw exception
	if (!root || root->getType() != BNode::DICT)
		throw new DecodingException(tr("Could not decode metainfo data."), Exception::Normal, __FILE__, __FUNCTION__, __LINE__);

	//Nadji vrednost info cvora
	BDictNode* r = dynamic_cast<BDictNode*>(root);
	const BNode* infoNode = r->value("info");
	const BDictNode* info = dynamic_cast<const BDictNode*>(infoNode);

	//Svaki Info nod ima 'name' clan koji je filename ako je singlefile torrent ili dirname ako je multi.
	const BValueNode* nameNode = dynamic_cast<const BValueNode*>(info->value("name"));
	const BNode* filesNode = info->value("files");			

	QStandardItem *item = new QStandardItem(QString(nameNode->value().toString()));
	rootItem->appendRow(item);
	rootItem = item;

	if (filesNode)
	{		
		const BListNode* files = dynamic_cast<const BListNode*>(filesNode);
		
		QHash<QString, QStandardItem*> hash;		

		//multifile torrent!
		for (int i = 0; i < files->children().count(); ++i)
		{
			const BDictNode* file = dynamic_cast<const BDictNode*>(files->children().value(i));
			const BListNode* path = dynamic_cast<const BListNode*>(file->value("path"));
					
			QStandardItem* parentItem = rootItem;
			QString dirPath;
			
			for(int j = 0; j < path->children().count(); ++j)
			{
				const BValueNode* n = dynamic_cast<const BValueNode*>(path->children().value(j));
				QString fn = n->value().toString();							
				
				dirPath += fn + "/";
				
				if(!hash.contains(dirPath))
				{
					///@TODO: Uvek postavlja ikonu, sredi to!
					QStandardItem* nItem = new QStandardItem(fn);
					hash.insert(dirPath, nItem);
					
					parentItem->appendRow(nItem);
					parentItem = nItem;
				}
				else
				{
					parentItem = hash.value(dirPath);
				}							
			}
		}
	}


	delete r;
	return model;
}
